package cn.huiyunche.driver.service.impl;

import cn.huiyunche.base.service.enums.AvailableEnum;
import cn.huiyunche.base.service.enums.GenderEnum;
import cn.huiyunche.base.service.enums.TmsUserTypeEnum;
import cn.huiyunche.base.service.enums.UserTypeEnum;
import cn.huiyunche.base.service.framework.security.JwtAuthenicationFilter;
import cn.huiyunche.base.service.interfaces.UserService;
import cn.huiyunche.base.service.mappers.*;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.utils.DateUtils;
import cn.huiyunche.base.service.vo.Result;
import cn.huiyunche.base.service.vo.TmsImportUserVo;
import cn.huiyunche.driver.service.TmsImportService;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.stereotype.Service;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * tms用户数据导入服务实现
 *
 * @author hdy [Tuffy]
 */
@Service
public class TmsImportServiceImpl implements TmsImportService {

    /**
     * 离职常量
     */
    private final String leaving = "离职";
    private final String A = "A";
    private final String B = "B";
    private final String C = "C";
    private final String default_password = "123456a";
    private final String classPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();

    @Autowired
    private DUserMapper dUserMapper = null;

    @Autowired
    private DUserExtMapper dUserExtMapper = null;

    @Autowired
    private DUserLicenseMapper dUserLicenseMapper = null;

    @Autowired
    private BLicenseTypeMapper bLicenseTypeMapper = null;

    @Autowired
    private Md5PasswordEncoder passwordEncoder = null;

    @Autowired
    private JwtAuthenicationFilter jwtAuthenticationFilter = null;

    @Autowired
    private SUserMapper sUserMapper = null;

    @Autowired
    private UserService userService = null;

    @SuppressWarnings("resource")
    @Override
    public Result<String> importUserExcel() {
        Result<String> r = new Result<>(true);
        String path = classPath + "driver.xlsx";
        InputStream is = null;
        List<TmsImportUserVo> data = new ArrayList<>();
        try {
            is = new FileInputStream(path);
            XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);
            XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0);
            for (int rowNum = 1; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
                XSSFRow xssfRow = xssfSheet.getRow(rowNum);
                TmsImportUserVo tiuv = new TmsImportUserVo();
                tiuv.setLicence(this.getXlsxValue(xssfRow.getCell(0)));
                tiuv.setRealName(this.getXlsxValue(xssfRow.getCell(1)));
                tiuv.setNativePlace(this.getXlsxValue(xssfRow.getCell(2)));
                tiuv.setBirthday(this.getXlsxValue(xssfRow.getCell(3)));
                tiuv.setIdCard(this.getXlsxValue(xssfRow.getCell(4)));
                tiuv.setPhone(this.getXlsxValue(xssfRow.getCell(5)));
                tiuv.setTelephone(this.getXlsxValue(xssfRow.getCell(6)));
                tiuv.setAddress(this.getXlsxValue(xssfRow.getCell(7)));
                tiuv.setCommunity(this.getXlsxValue(xssfRow.getCell(8)));
                tiuv.setIssuingAuthority(this.getXlsxValue(xssfRow.getCell(9)));
                tiuv.setReceiveDate(this.getXlsxValue(xssfRow.getCell(10)));
                tiuv.setLicenceType(this.getXlsxValue(xssfRow.getCell(11)));
                tiuv.setGuarantor(this.getXlsxValue(xssfRow.getCell(12)));
                tiuv.setTerm(this.getXlsxValue(xssfRow.getCell(13)));
                tiuv.setPicture(this.getXlsxValue(xssfRow.getCell(14)));
                tiuv.setStatus(this.getXlsxValue(xssfRow.getCell(15)));
                data.add(tiuv);
            }
            return this.importExcel(data);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return r;
    }

    @Override
    public List<TmsOrder> importOrderExcel() {
        String path = classPath + "order.xlsx";
        InputStream is = null;
        List<TmsOrder> data = new ArrayList<>();
        try {
            is = new FileInputStream(path);
            XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);
            XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0);
            for (int rowNum = 2; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
                XSSFRow xssfRow = xssfSheet.getRow(rowNum);
                TmsOrder to = new TmsOrder();
                Date thisDate = new Date();
                to.setCreateTime(thisDate);
                to.setDcqty(NumberUtils.toInt(this.getXlsxValue(xssfRow.getCell(6))));
                to.setDtassigndate(DateUtils.addDays(thisDate, 1));
                to.setDtcomedate(DateUtils.addDays(thisDate, 3));
                to.setDtcreatedate(DateUtils.StrToDate(this.getXlsxValue(xssfRow.getCell(2)), "yyyy/MM/dd HH:mm"));
                to.setDtorderdate(DateUtils.StrToDate(this.getXlsxValue(xssfRow.getCell(13)), "yyyy/MM/dd"));
                to.setDtshipdate(DateUtils.addDays(thisDate, 2));
                to.setIlineid(NumberUtils.toLong(rowNum + ""));
                to.setIurgent(0);
                to.setMemo(this.getXlsxValue(xssfRow.getCell(12)));
                to.setOpration(10);
                JSONObject j = new JSONObject();
                j.put("price", 0.01);
                j.put("km", 100);
                j.put("股份支付区域补贴", 22);
                j.put("股份固定费用扣除", -10);
                to.setOrdercost(j.toJSONString());
                to.setVcaddress("郑州");
                to.setVccityname(this.getXlsxValue(xssfRow.getCell(5)));
                to.setVccontact("张三");
                to.setVcdealername(this.getXlsxValue(xssfRow.getCell(3)));
                to.setVcdealerno("NO0001");
                to.setVcdestname(this.getXlsxValue(xssfRow.getCell(5)));
                to.setVcdestno("NO0002");
                to.setVcmobile("12345678901");
                to.setVcorderno(this.getXlsxValue(xssfRow.getCell(0)));
                to.setVcordertype("TMS");
                to.setVcprovincename(this.getXlsxValue(xssfRow.getCell(4)));
                to.setVcrequire("发运要求");
                to.setVcstartcity("北京");
                to.setVcstartprovince("北京");
                to.setVcstylename(this.getXlsxValue(xssfRow.getCell(10)));
                to.setVcstyleno("NO0003");
                to.setVctel("12345678902");
                to.setVctransname(this.getXlsxValue(xssfRow.getCell(7)));
                to.setVctransno("NO0004");
                to.setVcunit("辆");
                to.setVcvin(this.getXlsxValue(xssfRow.getCell(1)));
                to.setVcwarehouseaddress("司机中联提车库");
                to.setVcwarehousename("南昌");
                to.setVcwarehouseno("NO0005");
                to.setVehicledesc(this.getXlsxValue(xssfRow.getCell(10)));
                data.add(to);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * 导出数据
     *
     * @param importData
     * @return
     */
    private Result<String> importExcel(List<TmsImportUserVo> data) {
        Result<String> r = new Result<>(false);
        if (data.size() <= 0) {
            r.setMessage("数据不可为空");
            return r;
        }
        // 转换数据
        this.parseData(data);
        r.setSuccess(true);
        return r;
    }

    /**
     * 获取单元格数据
     *
     * @param xssfRow
     * @return
     */
    @SuppressWarnings({"static-access", "deprecation"})
    private String getXlsxValue(XSSFCell xssfRow) {
        if (xssfRow.getCellType() == xssfRow.CELL_TYPE_BOOLEAN) {
            return String.valueOf(xssfRow.getBooleanCellValue());
        } else if (xssfRow.getCellType() == xssfRow.CELL_TYPE_NUMERIC) {
            return String.valueOf(xssfRow.getNumericCellValue());
        } else {
            return String.valueOf(xssfRow.getStringCellValue());
        }
    }

    /**
     * 解析数据
     *
     * @param data 数据列表
     */
    private void parseData(List<TmsImportUserVo> data) {
        if (null == data || data.size() <= 0) {
            return;
        }
        // 执行用户信息
        for (TmsImportUserVo tiuv : data) {
            this.executionDUser(tiuv);
        }
    }

    /**
     * 操作用户信息
     *
     * @param tiuv 导入信息
     * @return 用户信息
     */
    private void executionDUser(TmsImportUserVo tiuv) {
        String phone = tiuv.getPhone();
        DUser du = this.getDUserByPhone(phone);
        // 添加用户
        if (null == du) {
            du = new DUser();
            this.addDUser(du, tiuv);
            return;
        }
        // 修改用户
        this.modifyDUser(du, tiuv);
    }

    /**
     * 获取duser
     *
     * @param phone 手机号
     * @return 用户对象
     */
    private DUser getDUserByPhone(String phone) {
        DUserExample due = new DUserExample();
        due.createCriteria().andLoginNameEqualTo(phone);
        List<DUser> list = this.dUserMapper.selectByExample(due);
        return list.size() > 0 ? list.get(0) : null;
    }

    /**
     * 修改用户
     *
     * @param du 用户对象
     */
    private void modifyDUser(DUser du, TmsImportUserVo tiuv) {
        this.assemblyDUser(du, tiuv);
        this.dUserMapper.updateByPrimaryKeySelective(du);
        // 修改用户扩展信息
        this.mofidyDUserExt(du, tiuv);
    }

    /**
     * 添加用户
     *
     * @param du   用户对象
     * @param tiuv 数据对象
     */
    private void addDUser(DUser du, TmsImportUserVo tiuv) {
        this.assemblyDUser(du, tiuv);
        du.setPwd(passwordEncoder.encodePassword(default_password, jwtAuthenticationFilter.getSecureKey()));
        du.setCreateTime(new Date());
        this.dUserMapper.insert(du);
        // 添加用户扩展信息
        this.addDUserExt(du, tiuv);
    }

    /**
     * 修改duser扩展信息
     *
     * @param du   用户对象
     * @param tiuv 数据对象
     */
    private void mofidyDUserExt(DUser du, TmsImportUserVo tiuv) {
        DUserExtExample duee = new DUserExtExample();
        duee.createCriteria().andUserIdEqualTo(du.getId());
        List<DUserExt> list = this.dUserExtMapper.selectByExample(duee);
        DUserExt due = list.size() > 0 ? list.get(0) : null;
        this.assemblyDUserExt(due, tiuv);
        this.dUserExtMapper.updateByPrimaryKeySelective(due);
        // 修改用户证件信息
        this.insertBLicenseType(du, tiuv);
        // 修改s_user信息
        SUser su = this.userService.getByPhone(du.getLoginName(), UserTypeEnum.SEND_DRIVER.getValue());
        this.assemblySUser(su, du, due, tiuv);
        this.sUserMapper.updateByPrimaryKeySelective(su);
    }

    /**
     * 添加duser扩展信息
     *
     * @param du   用户对象
     * @param tiuv 数据对象
     */
    private void addDUserExt(DUser du, TmsImportUserVo tiuv) {
        DUserExt due = new DUserExt();
        due.setUserId(du.getId());
        this.assemblyDUserExt(due, tiuv);
        this.dUserExtMapper.insert(due);
        // 添加用户证件信息
        this.insertBLicenseType(du, tiuv);
        // 添加s_user信息
        SUser su = new SUser();
        this.assemblySUser(su, du, due, tiuv);
        su.setUserStatus(20);
        this.sUserMapper.insert(su);
    }

    /**
     * 添加证件信息
     *
     * @param list 证件列表
     */
    private void insertBLicenseType(DUser du, TmsImportUserVo tiuv) {
        List<BLicenseType> list = this.parseLicenseType(tiuv);
        if (list.size() > 0) {
            // 删除证件信息
            List<Integer> typeList = new ArrayList<>();
            for (BLicenseType bt : list) {
                typeList.add(bt.getId());
            }
            DUserLicenseExample dule = new DUserLicenseExample();
            dule.createCriteria().andUserIdEqualTo(du.getId()).andSysLicenseIdIn(typeList);
            this.dUserLicenseMapper.deleteByExample(dule);
        }
        // 添加证件信息
        for (BLicenseType blt : list) {
            DUserLicense dul = new DUserLicense();
            dul.setUserId(du.getId());
            this.assemblyDUserLicence(dul, blt, tiuv);
            dul.setCreateTime(new Date());
            this.dUserLicenseMapper.insert(dul);
        }
    }


    /**
     * 解析证照
     *
     * @param tiuv 数据对象
     * @return 证照对象
     */
    private List<BLicenseType> parseLicenseType(TmsImportUserVo tiuv) {
        String licenseStr = tiuv.getLicenceType();
        if (StringUtils.isBlank(licenseStr)) {
            return null;
        }
        List<String> licenseList = new ArrayList<>();
        licenseStr = licenseStr.toUpperCase();
        // 解析 split A
        String[] aA = licenseStr.split(A);
        for (String a : aA) {
            if (!(a.contains(B) || a.contains(C))) {
                licenseList.add(A + a);
            } else if (a.contains(B)) {
                String[] bB = a.split(B);
                for (int i = 0; i < bB.length; i++) {
                    String bStr = bB[i];
                    if (i == 0) {
                        if (StringUtils.isNotBlank(bStr)) {
                            licenseList.add(A + bStr);
                        }
                    } else {
                        licenseList.add(B + bStr);
                    }
                }
            } else if (a.contains(C)) {
                String[] bB = a.split(C);
                for (int i = 0; i < bB.length; i++) {
                    String bStr = bB[i];
                    if (i == 0) {
                        if (StringUtils.isNotBlank(bStr)) {
                            licenseList.add(A + bStr);
                        }
                    } else {
                        licenseList.add(C + bStr);
                    }
                }
            }
        }
        // 数据匹配
        BLicenseTypeExample blte = new BLicenseTypeExample();
        blte.createCriteria().andLicenseNameIn(licenseList);
        return this.bLicenseTypeMapper.selectByExample(blte);
    }

    /**
     * 组装s用户信息
     *
     * @param su   s用户
     * @param du   d用户
     * @param due  d用户扩展信息
     * @param tiuv 数据
     */
    private void assemblySUser(SUser su, DUser du, DUserExt due, TmsImportUserVo tiuv) {
        if (null == su) {
            su = new SUser();
        }
        su.setBirthday(due.getBirthday());
        su.setEnable(du.getEnable() ? AvailableEnum.T.getValue() : AvailableEnum.F.getValue());
        su.setGender(due.getGender());
        su.setName(due.getUserName());
        su.setPhone(due.getPhone());
        su.setRealName(due.getRealName());
        su.setUserType(UserTypeEnum.SEND_DRIVER.getValue());
        su.setPwd(passwordEncoder.encodePassword(default_password, jwtAuthenticationFilter.getSecureKey()));
    }

    /**
     * 组装用户证件数据
     *
     * @param dul  证件数据对象
     * @param blt  证件类型
     * @param tiuv 数据对象
     */
    private void assemblyDUserLicence(DUserLicense dul, BLicenseType blt, TmsImportUserVo tiuv) {
        if (null == dul) {
            dul = new DUserLicense();
        }
        dul.setLicenseName(blt.getLicenseName());
        dul.setLicenseDept(tiuv.getIssuingAuthority());
        String receiveDate = tiuv.getReceiveDate();
        if (StringUtils.isBlank(receiveDate)) {
            dul.setReceiveTime(new Date());
        } else {
            dul.setReceiveTime(DateUtils.StrToDate(receiveDate, "yyyy/MM/dd"));
        }
        dul.setSysLicenseId(blt.getId());
    }

    /**
     * 组装用户数据
     *
     * @param du   用户对象
     * @param tiuv 数据对象
     */
    private void assemblyDUser(DUser du, TmsImportUserVo tiuv) {
        if (null == du) {
            du = new DUser();
        }
        String status = tiuv.getStatus();
        // 离职
        if (status.trim().equals(leaving)) {
            du.setEnable(false);
        } else {
            du.setEnable(true);
        }
        du.setLoginName(tiuv.getPhone());
        du.setType(TmsUserTypeEnum.DRIVER.getValue());
    }

    /**
     * 组装数据
     *
     * @param due  扩展对象
     * @param tiuv 数据对象
     */
    private void assemblyDUserExt(DUserExt due, TmsImportUserVo tiuv) {
        if (null == due) {
            due = new DUserExt();
        }
        String userName = tiuv.getRealName();
        due.setUserName(userName);
        due.setRealName(userName);
        due.setGender(GenderEnum.T.getValue());
        due.setBirthplace(tiuv.getNativePlace());
        String birthday = tiuv.getBirthday();
        if (StringUtils.isNotBlank(birthday)) {
            due.setBirthday(DateUtils.StrToDate(birthday, "yyyy/MM/dd"));
        }
        due.setIdNo(tiuv.getIdCard().replaceAll("No.", ""));
        due.setPhone(tiuv.getPhone());
        due.setHomePhone(tiuv.getTelephone());
        due.setHomeAddress(tiuv.getAddress());
        due.setGuarantor(tiuv.getGuarantor());
        due.setImage(tiuv.getPicture());
        due.setCreateTime(new Date());
    }

}
